﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.Windows.Media.Imaging;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using MotionCS;
using System.Windows;
using MotionCS.Helper;
using MotionCS.CameraVision;
using MotionCS.Enumerate;
using System.Windows.Media.Media3D;
using System.Windows.Controls;
using System.Diagnostics.Eventing.Reader;
using System.Diagnostics;
using System.Windows.Interop;
using System.Runtime.CompilerServices;
using MotionCS.Config;
using static MotionCS.MotionLib;
using System.ComponentModel;
using System.Windows.Media;
using System.Windows.Input;

namespace Motion
{
    public class MainViewModel : ViewModelBase
    {
        //日志输出
        static bool outLog = false;
        public string MainModel { get; set; }
        public string AlarmContent { get; set; }

        public bool IsOffLine = true;


        //public event PropertyChangedEventHandler PropertyChanged2;
        //protected virtual void OnPropertyChanged(string propertyName)
        //{
        //    PropertyChanged2?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        //}
        /// <summary>
        /// 1123
        /// </summary>

        private string _myText = "直通模式开";
        public string MyText
        {
            get => _myText;
            set { _myText = value; RaisePropertyChanged(); /*OnPropertyChanged(nameof(_myText)); */}
        }
       // public SolidColorBrush ButtonColor { get; set; } = new SolidColorBrush(Colors.Green);

        private SolidColorBrush _buttonColor;

        public SolidColorBrush ButtonColor
        {
            get => _buttonColor;
            set
            {
                _buttonColor = value;
                 RaisePropertyChanged();
               // OnPropertyChanged(nameof(ButtonColor));
            }
        }
        //public event PropertyChangedEventHandler PropertyChanged2;
        //protected virtual void OnPropertyChanged(string propertyName)
        //{
        //    PropertyChanged2?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        //}



        private float t_Width;
        public float T_Width
        {
            get => t_Width;
            set
            {
                t_Width = value;
                RaisePropertyChanged();
            }
        }


        /// <summary>
        /// X轴实际速度
        /// </summary>
        private string xActSpeed;
        public string XActSpeed 
        {
            get => xActSpeed;
            set
            {
                xActSpeed = value;
                RaisePropertyChanged();
            }
        }
        /// <summary>
        /// Y轴实际速度
        /// </summary>
        private string yActSpeed;
        public string YActSpeed 
        { 
            get => yActSpeed;
            set
            {
                yActSpeed = value;
                RaisePropertyChanged();
            }
        }
        private string wActSpeed;
        public string WActSpeed 
        { 
            get => wActSpeed;
            set
            {
                wActSpeed = value;
                RaisePropertyChanged();
            }
        }

        private string tActSpeed;
        public string TActSpeed
        {
            get => tActSpeed;
            set
            {
                tActSpeed = value;
                RaisePropertyChanged();
            }
        }

        private string xActPos;
        public string XActPos 
        {
            get => xActPos;
            set
            {
                xActPos = value;
                RaisePropertyChanged();
            } 
        }

        private string yActPos;
        public string YActPos 
        { 
            get => yActPos;
            set
            {
                yActPos = value;
                RaisePropertyChanged();
            }
        }

        private string wActPos;
        public string WActPos 
        { 
            get => wActPos;
            set
            {
                wActPos = value;
                RaisePropertyChanged();
            } 
        }

        /// <summary>
        /// 调试日志
        /// </summary>
        private string logText;
        public string LogText
        {
            get => logText;
            set
            {
                logText = value;
                RaisePropertyChanged();
            }
        }

       
     
        public bool IsCameraContinue { get; set; }
        public bool IsRailContinue { get; set; }

     
        private bool isNOSafeDoor;
        public bool IsNOSafeDoor
        {
            get => isNOSafeDoor;
            set
            {
                isNOSafeDoor = value;
                RaisePropertyChanged();
            }
        }


        public float CameraStepValue { get; set; }
        public float RailStepValue { get; set; }
        public List<float> StepItemSource { get; set; }


        public float xstepPosi { get; set; }
        public float ystepPosi { get; set; }
        public float ZMovePosi { get; set; }

        public float ProductLength { get; set; }
        public float ProductWidth { get; set; }

        public event Action<string> LogoutEvent;

        private MotionLib motion;

        private Thread runThread;

        private string selectedModuleName;
        public string SelectedModuleName 
        {
            get => selectedModuleName;
            set 
            {
                selectedModuleName = value; this.RaisePropertyChanged();
            }
        }

        private ObservableCollection<string> modulesItemSource = new ObservableCollection<string>();
        public ObservableCollection<string> ModulesItemSource
        {
            get => modulesItemSource;
            set
            {
                modulesItemSource = value; this.RaisePropertyChanged();
            }
        }

        private ObservableCollection<IoModel> diItemSource;
        public ObservableCollection<IoModel> DiItemSource
        {
            get { return diItemSource; }
            set { diItemSource = value; this.RaisePropertyChanged(); }
        }

        private ObservableCollection<IoModel> doItemSource;
        public ObservableCollection<IoModel> DoItemSource
        {
            get { return doItemSource; }
            set { doItemSource = value; this.RaisePropertyChanged(); }
        }

        private bool isClientConnect = false;

        public bool IsClientConnect
        {
            get { return isClientConnect; }
            set { isClientConnect = value; RaisePropertyChanged(); }
        }


        private BitmapImage imageSource;
        public BitmapImage ImageSource
        {
            get => imageSource;
            set
            {
                imageSource = value;
                this.RaisePropertyChanged();
            }
        }

        private bool isConnected = true;
        public bool IsConnected
        {
            get => isConnected;
            set
            {
                isConnected = value;
                RaisePropertyChanged();
            }
        }
        /// <summary>
        /// 保存图片
        /// </summary>
        private bool isSaveJpg = true;
        public bool IsSaveJpg
        {
            get => isSaveJpg;
            set
            {
                isSaveJpg = value;
                this.RaisePropertyChanged("IsSaveJpg");
            }
        }

        /// <summary>
        /// 相机通道
        /// </summary>
        private List<CameraConf> cameras;
        public MainViewModel()
        {
          
            _myText = "直通模式开";
            _buttonColor = new SolidColorBrush(Colors.Green);
            InitView();

            //初始化通信模块
            if (IntCommunication() == 1)
            {
                CommunicationLoopMsg();
                CommunicationHeartMsg();
            }

            motion = new MotionLib();

            cameras = motion.MT_MachineInit(HikImageCallback, LogCallback);
          
            if (cameras.Count == 0)
            {
              
                IsConnected = false;
                return;
            }
          
            motion.RegisterModuleStateCallback(new Action<int, ModuleTaskStateE>((camNo, state) =>
            {
                cameras.Find(itm => itm.CamNo == camNo).TaskState = state;
            }));

            selectedModuleName = cameras[0].CamName;
            cameras.ForEach(p =>
            {
                ModulesItemSource.Add(p.CamName);
            });

            runThread = new Thread(new ThreadStart(RunThread));
            runThread.IsBackground = true;
            runThread.Start();
        }

        private void InitView()
        {
         

            StepItemSource = new List<float>() { 0.1f, 0.5f, 1, 5, 10 };
            isNOSafeDoor = true;
            IsCameraContinue = true;
          
            IsRailContinue = true;

            ProductWidth = 200;
            ProductLength = 300;

            //UpdateGrabIndex();//-LZC  20230606
            DiItemSource = new ObservableCollection<IoModel>();
            DoItemSource = new ObservableCollection<IoModel>();
            for (int i = 0; i < 32; i++)
            {
                DiItemSource.Add(new IoModel
                {
                    ID = i,
                    Name = "",
                    Content = "",
                    IsChecked = (i % 2) == 0 ? false : true
                });
                DoItemSource.Add(new IoModel
                {
                    ID = i,
                    Name = "",
                    Content = "",
                    IsChecked = false,
                });
            }
        }

        int m_nResetButton = 0;
        DateTime ResetTime;

        bool m_bWidthStart = false;
        int m_nWidthMode = 0;
        DateTime WidthTime;

        bool m_bWidthMove1 = false;
        bool m_bWidthMove2 = false;
        private void RunThread()
        {
            double xAxisPos = 0f;
            double yAxisPos = 0f;
            double wAxisPos = 0f;
            double xAxisSpeed = 0f;
            double yAxisSpeed = 0f;
            double wAxisSpeed = 0f;
            double tAxisSpeed = 0f;
            uint[] inst = new uint[2];//2张卡
            uint[] outst = new uint[2];


            for (; ; )
            {
                motion.MT_GetAxisPosition(GetCurrentCamera(), AxisE.X, ref xAxisPos);
                motion.MT_GetAxisPosition(GetCurrentCamera(), AxisE.Y, ref yAxisPos);
                motion.MT_GetAxisPosition(GetCurrentCamera(), AxisE.W, ref wAxisPos);
                motion.MT_GetAxisSpeed(GetCurrentCamera(), AxisE.X, ref xAxisSpeed);
                motion.MT_GetAxisSpeed(GetCurrentCamera(), AxisE.Y, ref yAxisSpeed);
                motion.MT_GetAxisSpeed(GetCurrentCamera(), AxisE.W, ref wAxisSpeed);
                motion.MT_GetAxisSpeed(GetCurrentCamera(), AxisE.T, ref tAxisSpeed);

                motion.MTGetAllInputBit(ref inst[0], 0);
                //motion.MTGetAllInputBit(ref inst[1], 1);
                UpdateINStatus(inst);
                motion.MTGetAllOutputBit(ref outst[0], 0);
                //motion.MTGetAllOutputBit(ref inst[1], 1);
                UpdateOUTStatus(outst);

                XActPos = xAxisPos.ToString("0.00");
                YActPos = yAxisPos.ToString("0.00");
                WActPos = wAxisPos.ToString("0.00");
                XActSpeed = xAxisSpeed.ToString("0.00");
                YActSpeed = yAxisSpeed.ToString("0.00");
                WActSpeed = wAxisSpeed.ToString("0.00");
                TActSpeed = tAxisSpeed.ToString("0.00");

                bool bUseSafeDoor = isNOSafeDoor;
                motion.MT_ChangeSafedoor(bUseSafeDoor);
                Thread.Sleep(50);

                if (  DiItemSource[3].IsChecked && DiItemSource[2].IsChecked)
                {
                    if (m_nWidthMode == 0)
                    {
                        m_nWidthMode = 1;
                        WidthTime = DateTime.Now;
                    }
                    else if (m_nWidthMode == 1 && !m_bWidthStart)
                    {
                        TimeSpan span = DateTime.Now - WidthTime;
                        if (span.TotalMilliseconds >= 3000)   //长按3秒进去调宽模式
                        {
                            m_bWidthStart = true;
                            motion.MT_OpenBeep(GetCurrentCamera());
                            Thread.Sleep(500);
                            motion.MT_CloseBeep(GetCurrentCamera());
                        }
                    }
                     continue;
                }
                if (m_nWidthMode == 1)
                    m_nWidthMode = 0; 
                
                if (m_bWidthStart)   //调宽模式
                {
                    if (DiItemSource[2].IsChecked)  //点启动,调宽-
                    {
                        if (m_bWidthMove1 == false)
                        {
                            MoveDirRelay("调窄"); m_bWidthMove1 = true;
                        }
                    }
                    else
                    {
                        if (m_bWidthMove1)
                        {
                            m_bWidthMove1 = false;
                             motion.MT_MoveStop(GetCurrentCamera(), AxisE.W);
                        }
                    }

                    if (DiItemSource[4].IsChecked)  //点停止,退出调宽模式
                    {
                        m_bWidthMove1 = false; m_bWidthMove2 = false;
                        motion.MT_MoveStop(GetCurrentCamera(), AxisE.W);
                        m_bWidthStart = false;//退出调宽模式
                        motion.MT_OpenBeep(GetCurrentCamera());
                        Thread.Sleep(500);
                        motion.MT_CloseBeep(GetCurrentCamera());
                    }
                }
                else
                {

                    if (DiItemSource[2].IsChecked)  //点启动,进板
                    {
                        motion.MT_ConveyorInput(GetCurrentCamera());
                    }
                   
                    if (DiItemSource[4].IsChecked)  //点停止,出板
                    {
                        motion.MT_ConveyorOutput(GetCurrentCamera());
                    }
                }
                if (DiItemSource[3].IsChecked)
                {
                    if (m_bWidthStart )                //调宽+
                    {
                        if (m_bWidthMove2 == false)
                        {
                            MoveDirRelay("调宽"); m_bWidthMove2 = true;
                        }
                    }
                    else
                    {
                        if (m_nResetButton == 0)
                        {
                            ResetTime = DateTime.Now;
                            m_nResetButton = 1;
                        }
                        else if (m_nResetButton == 1)
                        {

                            TimeSpan span = DateTime.Now - ResetTime; 
                            Thread.Sleep(100);
                            if (span.TotalMilliseconds >= 3000)   //复位
                            {

                                // ProductCheckRelay("复位");
                                m_nResetButton = 2;
                                motion.MT_StopDetect(cameras);

                                //ButtonColor = new SolidColorBrush(Colors.Green);
                                //MyText = "直通模式开";
                                //m_bPassMode = false;
                               // ProductCheckRelay

                                motion.MT_MachineReset(GetCurrentCamera());

                            }
                        }
                      
                    }
                }
                else
                {
                    if (m_bWidthStart)                //
                    {
                        if (m_bWidthMove2)
                        {
                            m_bWidthMove2 = false;
                            motion.MT_MoveStop(GetCurrentCamera(), AxisE.W);
                        }
                    }
                  

                    if (m_nResetButton == 1)
                    {
                        TimeSpan span = DateTime.Now - ResetTime;
                        if (span.TotalMilliseconds < 1000)
                        {
                            motion.MT_ConveyorReturn(GetCurrentCamera());
                        }
                    }
                    if (m_nResetButton == 2 || m_nResetButton == 1)
                        m_nResetButton = 0;
                }
            }
        }

        /// <summary>
        /// 更新输入IO状态
        /// </summary>
        /// <param name="inst"></param>
        private void UpdateINStatus(uint[] inst)
        {
            for (int i = 0; i < DiItemSource.Count; i++)
            {
                uint st = DiItemSource[i].ID < 32 ? inst[0] : inst[1];
                int idx = DiItemSource[i].ID < 32 ? DiItemSource[i].ID : DiItemSource[i].ID - 32;
                if (((st >> idx) & 0x01) == 0x01)
                {
                    DiItemSource[i].IsChecked = false;
                }
                else
                {
                    DiItemSource[i].IsChecked = true;
                }
            }
        }
        /// <summary>
        /// 更新输出IO状态
        /// </summary>
        /// <param name="outst"></param>
        private void UpdateOUTStatus(uint[] outst)


        {
            for (int i = 0; i < DoItemSource.Count; i++)
            {
                if (((outst[0] >> DoItemSource[i].ID) & 0x01) == 0x01)
                {
                    DoItemSource[i].IsChecked = false;
                }
                else
                {
                    DoItemSource[i].IsChecked = true;
                }
            }
        }

        #region 命令
        /// <summary>
        /// 窗体关闭
        /// </summary>
        private RelayCommand windowClosedCmd;
        public RelayCommand WindowClosedCmd
        {
            get
            {
                if (windowClosedCmd == null)
                {
                    windowClosedCmd = new RelayCommand(() =>
                    {
                        motion.MT_MachineDispose();
                        LoopTestCameras.Clear();
                    });
                }
                return windowClosedCmd;
            }
        }
        private RelayCommand<int> doControlCmd;
        public RelayCommand<int> DoControlCmd
        {
            get
            {
                if (doControlCmd == null)
                {
                    doControlCmd = new RelayCommand<int>((p) => DoControlRelay(p));
                }
                return doControlCmd;
            }
        }

        private RelayCommand<bool> cameraGrabCmd;
        public RelayCommand<bool> CameraGrabCmd
        {
            get
            {
                if (cameraGrabCmd == null)
                {
                    cameraGrabCmd = new RelayCommand<bool>((p) => CameraGrabRelay(p));
                }
                return cameraGrabCmd;
            }
        }

        private RelayCommand<string> camMoveDirCmd;
        public RelayCommand<string> CamMoveDirCmd
        {
            get 
            { 
                if (camMoveDirCmd == null)
                {
                    camMoveDirCmd = new RelayCommand<string>((p) => CamMoveDirRelay(p));
                }
                return camMoveDirCmd;
            }
        }

        private RelayCommand<string> camMoveStopCmd;
        public RelayCommand<string> CamMoveStopCmd
        {
            get
            {
                if (camMoveStopCmd == null)
                {
                    camMoveStopCmd = new RelayCommand<string>((p) => CamMoveStopRelay(p));
                }
                return camMoveStopCmd;
            }
        }
        private RelayCommand<string> railMoveDirCmd;
        public RelayCommand<string> RailMoveDirCmd
        {
            get
            {
                if (railMoveDirCmd == null)
                {
                    railMoveDirCmd = new RelayCommand<string>((p) => RailMoveDirRelay(p));
                }
                return railMoveDirCmd;
            }
        }

        private RelayCommand<string> railMoveStopCmd;
        public RelayCommand<string> RailMoveStopCmd
        {
            get
            {
                if (railMoveStopCmd == null)
                {
                    railMoveStopCmd = new RelayCommand<string>((p) => RailMoveStopRelay(p));
                }
                return railMoveStopCmd;
            }
        }

        private RelayCommand<string> xAxisMoveCmd;
        public RelayCommand<string> XAxisMoveCmd
        {
            get
            {
                if (xAxisMoveCmd == null)
                {
                    xAxisMoveCmd = new RelayCommand<string>((p) => XAxisMoveRelay(p));
                }
                return xAxisMoveCmd;
            }
        }

        private RelayCommand<string> yAxisMoveCmd;
        public RelayCommand<string> YAxisMoveCmd
        {
            get
            {
                if (yAxisMoveCmd == null)
                {
                    yAxisMoveCmd = new RelayCommand<string>((p) => YAxisMoveRelay(p));
                }
                return yAxisMoveCmd;
            }
        }

        private RelayCommand<string> wAxisMoveCmd;
        public RelayCommand<string> WAxisMoveCmd
        {
            get
            {
                if (wAxisMoveCmd == null)
                {
                    wAxisMoveCmd = new RelayCommand<string>((p) => WAxisMoveRelay(p));
                }
                return wAxisMoveCmd;
            }
        }

        private RelayCommand<string> beltMoveCmd;
        public RelayCommand<string> BeltMoveCmd
        {
            get
            {
                if (beltMoveCmd == null)
                {
                    beltMoveCmd = new RelayCommand<string>((p) => BeltMoveRelay(p));
                }
                return beltMoveCmd;
            }
        }

        private RelayCommand<string> productCheckCmd;
        public RelayCommand<string> ProductCheckCmd
        {
            get
            {
                if (productCheckCmd == null)
                {
                    productCheckCmd = new RelayCommand<string>((p) => ProductCheckRelay(p));
                }
                return productCheckCmd;
            }
        }

        private void DoControlRelay(int p)
        {
            //int val = StatusMonitor.IooutStatus(p);
            //motion.MT_SetOutStatus(p, (uint)(val == 1 ? 0: 1));
        }

        private void CameraGrabRelay(bool isChecked)
        {
            if (isChecked)
            {
                motion.MT_StartGrabImage(GetCurrentCamera());
            }
            else
            {
                var cam = GetCurrentCamera();
                cam.LightType = GrabLightTypeE.RGBAndWhiteAndDLP;
                motion.MT_GrabSingleImage(cam);
            }
        }

        private void CamMoveDirRelay(string p)
        {
            if (IsCameraContinue)
            {
                MoveDirRelay(p);
            }
            else
            {
                MoveRelRelay(p);
            }
        }

        private void CamMoveStopRelay(string p)
        {
            if (IsCameraContinue)
            {
                MoveStopRelay(p);
            }
        }

        private void RailMoveDirRelay(string p)
        {
            if (IsRailContinue)
            {
                MoveDirRelay(p);
            }
            else
            {
                MoveRelRelay(p);
            }
        }

        private void RailMoveStopRelay(string p)
        {
            if (IsRailContinue)
            {
                MoveStopRelay(p);
            }
        }

        private CameraConf GetCurrentCamera()
        {
            if (cameras == null) return null;
            return cameras.Find(p => p.CamName == selectedModuleName);
        }

        private void MoveDirRelay(string p)  //一直移动
        {
            switch (p)
            {
                case "左上":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.X, -1);
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.Y, -1);
                    break;
                case "右上":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.X, 1);
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.Y, -1);
                    break;
                case "左下":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.X, -1);
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.Y, 1);
                    break;
                case "右下":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.X, 1);
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.Y, 1);
                    break;
                case "向上":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.Y, -1);
                    break;
                case "向下":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.Y, 1);
                    break;
                case "向左":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.X, -1);
                    break;
                case "向右":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.X, 1);
                    break;
                case "调宽":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.W, 1);
                    break;
                case "调窄":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.W, -1);
                    break;
            }
        }

        private void MoveStopRelay(string p)
        {
            switch (p)
            {
                case "左上":
                case "右上":
                case "左下":
                case "右下":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.X);
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.Y);
                    break;
                case "向上":
                case "向下":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.Y);
                    break;
                case "向左":
                case "向右":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.X);
                    break;
                case "调宽":
                case "调窄":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.W);
                    break;
                case "停止":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.X);
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.Y);
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.T);
                   

                    break;

            }
        }


        private void MoveRelRelay(string p) //位置移动
        {
            switch (p)
            {
                case "左上":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.X, -CameraStepValue);
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.Y, -CameraStepValue);
                    break;
                case "右上":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.X, CameraStepValue);
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.Y, -CameraStepValue);
                    break;
                case "左下":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.X, -CameraStepValue);
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.Y, CameraStepValue);
                    break;
                case "右下":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.X, CameraStepValue);
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.Y, CameraStepValue);
                    break;
                case "向上":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.Y, -CameraStepValue);
                    break;
                case "向下":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.Y, CameraStepValue);
                    break;
                case "向左":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.X, -CameraStepValue);
                    break;
                case "向右":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.X, CameraStepValue);
                    break;
                case "调宽":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.W, RailStepValue);
                    break;
                case "调窄":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.W, -RailStepValue);
                    break;
            }
        }

        private void XAxisMoveRelay(string p)
        {
            switch (p)
            {
                case "相对":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.X, xstepPosi);
                    break;
                case "绝对":
                    motion.MT_MoveAbs(GetCurrentCamera(), AxisE.X, xstepPosi);
                    break;
                case "回零":
                    motion.MT_MoveHome(GetCurrentCamera(), AxisE.X);
                    break;
                case "停止":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.X);
                    break;
            }
        }

        private void YAxisMoveRelay(string p)
        {
            switch (p)
            {
                case "相对":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.Y, ystepPosi);
                    break;
                case "绝对":
                    motion.MT_MoveAbs(GetCurrentCamera(), AxisE.Y, ystepPosi);
                    break;
                case "回零":
                    motion.MT_MoveHome(GetCurrentCamera(), AxisE.Y);
                    break;
                case "停止":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.Y);
                    break;
            }
        }

        private void WAxisMoveRelay(string p)
        {
            switch (p)
            {
                case "相对":
                    motion.MT_MoveRel(GetCurrentCamera(), AxisE.W, ZMovePosi);
                    break;
                case "绝对":
                    motion.MT_MoveAbs(GetCurrentCamera(), AxisE.W, ZMovePosi);
                    break;
                case "回零":
                    motion.MT_MoveHome(GetCurrentCamera(), AxisE.W);
                    break;
                case "停止":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.W);
                    break;
            }
        }

        private void BeltMoveRelay(string p)
        {
            switch (p)
            {
                case "左到右":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.T, 1);
                    break;
                case "右到左":
                    motion.MT_MoveDir(GetCurrentCamera(), AxisE.T, -1);
                    break;
                case "停止":
                    motion.MT_MoveStop(GetCurrentCamera(), AxisE.T);
                    break;
            }
        }


        bool  m_bPassMode   = false;
        private void ProductCheckRelay(string p)
        {
            switch (p)
            {
                case "复位":
                    motion.MT_StopDetect(cameras);
                    ButtonColor = new SolidColorBrush(Colors.Green);
                    MyText = "直通模式开";
                    Thread.Sleep(300);
                    m_bPassMode = false;
                    m_bWidthStart = false;
                    motion.MT_MachineReset(GetCurrentCamera());
                    break;

                case "复运行":
                    motion.MT_StopDetect(cameras);
                    MessageHeader msg = new MessageHeader();
                    msg.CmdType = CommandType.Running;
                    StartRuningCmd(msg);
                    break;
                case "调宽":
                    motion.MT_SetConveyorWidth(GetCurrentCamera(), T_Width);
                    break;
                case "读宽度":
                    float fWidth = 0;
                    motion.MT_GetConveyorWidth(GetCurrentCamera(),ref fWidth);
                    T_Width = fWidth;
                    break;
                case "直通模式开":

                    motion.MT_StopDetect(cameras);

                    Thread.Sleep(300);
                    m_bWidthStart = false;

                    ButtonColor = new SolidColorBrush(Colors.Red);
                    MyText = "直通中..."; m_bPassMode = true;
                    System.Windows.MessageBox.Show("开启直通模式","提示",MessageBoxButton.OK, MessageBoxImage.Information );
                  
                    cameras.ForEach(itm =>
                    {
                        itm.Length = ProductLength;
                        itm.Width = ProductWidth;
                        itm.LightType = GrabLightTypeE.RGBAndWhiteAndDLP;
                    });

                    MotionLib.MT_Status status = motion.MT_PassDetect(cameras);
                    if (status.Code != MotionLib.MT_OK)
                    {
                        m_bPassMode = false;
                        ButtonColor = new SolidColorBrush(Colors.Green);
                        MyText = "直通模式开";
                        System.Windows.MessageBox.Show("直通模式开启失败,请复位软件", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                     break;

               
                case "直通中...":
                    motion.MT_StopDetect(cameras);
                    m_bPassMode = false;
                    ButtonColor = new SolidColorBrush(Colors.Green);
                    MyText = "直通模式开";
                    System.Windows.MessageBox.Show("关闭直通模式", "提示", MessageBoxButton.OK, MessageBoxImage.Information);

                 
                    break;

                case "进板":
                    motion.MT_ConveyorInput(GetCurrentCamera());
                    break;
               
                case "下料位":
                    motion.MT_ConveyorOutput(GetCurrentCamera());
                    break;

                case "上料位":
                    motion.MT_ConveyorReturn(GetCurrentCamera());
                    break;
                case "开启蜂鸣器":
                    motion.MT_OpenBeep(GetCurrentCamera());
                    break;
                case "关闭蜂鸣器":
                    motion.MT_CloseBeep(GetCurrentCamera());
                    break;



                //case "开始检测":
                //    cameras.ForEach(itm =>
                //    {
                //        itm.Length = ProductLength;
                //        itm.Width = ProductWidth;
                //        itm.LightType = GrabLightTypeE.RGBAndWhiteAndDLP;
                //    });

                //    motion.MT_StartDetect(cameras);
                //    break;
                //case "停止检测":
                //    motion.MT_StopDetect(cameras);
                //    break;
                //case "整机拍照":
                //    CameraConf conf = GetCurrentCamera();
                //    conf.Length = ProductLength;
                //    conf.Width = ProductWidth;
                //    conf.LightType = GrabLightTypeE.RGBLight;//GrabLightTypeE.RGBAndWhiteAndDLP;
                //    //conf.GrabPoints = new List<GrabPointConfig>()
                //    //{
                //    //    { new GrabPointConfig(10, 20, 30, 50, GrabPositionTypeE.Normal, GrabLightTypeE.RGBLight) },
                //    //    { new GrabPointConfig(50, 70, 30, 50, GrabPositionTypeE.Normal, GrabLightTypeE.WhiteLight) },
                //    //    { new GrabPointConfig(80, 150, 30, 50, GrabPositionTypeE.Normal, GrabLightTypeE.RGBAndWhite) },
                //    //    { new GrabPointConfig(50, 20, 10, 10, GrabPositionTypeE.Normal, GrabLightTypeE.RGBLight) },
                //    //    { new GrabPointConfig(50, 70, 10, 10, GrabPositionTypeE.Normal, GrabLightTypeE.WhiteLight) },
                //    //    { new GrabPointConfig(80, 50, 10, 10, GrabPositionTypeE.Normal, GrabLightTypeE.RGBAndWhite) },
                //    //};
                //    motion.MT_StartGrabImage(conf);
                //    break;
            }
        }
        #endregion

        #region 相机图像
        /// <summary>
        /// 获取图片编码
        /// </summary>
        /// <param name="format"></param>
        /// <returns></returns>
        private ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                    return codec;
            }
            return null;
        }

        /// <summary>
        /// bitmap转字节流
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        private BitmapImage ToBitmapImage(Bitmap bitmap)
        {
            // 1.先将BitMap转成内存流
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);
            // 2.再将内存流转成byte[]并返回
            byte[] bytes = new byte[ms.Length];
            ms.Read(bytes, 0, bytes.Length);
            ms.Dispose();
            // 3.byte转bitmapImage
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = new MemoryStream(bytes);
            bitmapImage.EndInit();
            return bitmapImage;
        }
        bool isF = true;
        Stopwatch stopwatch = new Stopwatch();
        Stopwatch stopwatch_1 = new Stopwatch();
        // 创建一个字节数组来接收数据
        private byte[] hikFrameData = null;
        /// <summary>
        /// 图片存储
        /// </summary>
        /// <param name="objGxSingleCam"></param>
        /// <param name="hikFrame"></param>
        private void HikImageCallback(IFrameData hikFrame)
        {
            stopwatch.Restart();
            if (hikFrameData == null)
                hikFrameData = new byte[hikFrame.RawLen];

            // 使用 Marshal.Copy 从 IntPtr 拷贝数据到字节数组
            Marshal.Copy(hikFrame.RawPtr, hikFrameData, 0, hikFrame.RawLen);

            ImageData imageData = new ImageData();
            long.TryParse(hikFrame.Uuid, out long msgID);
            byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(hikFrame.QrCode);

            imageData.ImageBufferLength = hikFrameData.Length;
            imageData.BarCodeLength = byteArray.Length;
            imageData.Index = hikFrame.Index;
            imageData.Uuid = msgID;
            imageData.Channel = ++ImgCount;
            imageData.Length = hikFrame.Width;
            imageData.Width = hikFrame.Height;
            imageData.DlpImageIndex = hikFrame.DlpImageIndex;
            imageData.DlpLocationIndex = hikFrame.DlpLocationIndex;
            imageData.bReaded = false;
            CommunicationServerHelper.Instance.SendOneImageDataAndBuffer(CurrentID, imageData, ref byteArray, ref hikFrameData);

            Logger.Logout($"{DateTime.Now.ToString("yyyyMMddHHmmssfff")},CurrentID:{CurrentID},imgID:{imageData.Index}+{imageData.DlpImageIndex},{stopwatch.ElapsedMilliseconds}ms");
            LogCallback($"{DateTime.Now.ToString("yyyyMMddHHmmssfff")},CurrentID:{CurrentID},imgID:{imageData.Index}+{imageData.DlpImageIndex},{stopwatch.ElapsedMilliseconds}ms");

           // Logger.Logout($"{DateTime.Now.ToString("yyyyMMddHHmmssfff")},{imageData.Index},{CurrentID},{imageData.DlpImageIndex},{stopwatch.ElapsedMilliseconds}ms");
           // LogCallback($"{DateTime.Now.ToString("yyyyMMddHHmmssfff")},{imageData.Index},{CurrentID},{imageData.DlpImageIndex},{stopwatch.ElapsedMilliseconds}ms");

            //if (imageData.Index == 1 && isF)
            //    {
            //        isF = false;
            //        stopwatch_1.Restart();
            //    }
            //if (imageData.Index == 40 && hikFrame.DlpImageIndex == 3)
            //    {
            //        isF = true;
            //        LogCallback($"{DateTime.Now.ToString("yyyyMMddHHmmssfff")},单次耗时{stopwatch_1.ElapsedMilliseconds}ms");
            //    }
            CurrentID = (CurrentID + 1) % 100;
            return;
            #region old
            App.Current.Dispatcher.Invoke(new Action(() =>
            {
                //ImageData = BitmapToBytes(hikFrame.ToBitmap());
                ImageSource = ToBitmapImage(hikFrame.ToBitmap());
            }));

            Bitmap bitmap = hikFrame.ToBitmap();

            DateTime date = DateTime.Now;
            string savePath = Path.Combine(@"D:\Cam", "Hikvision", hikFrame.SerialNo);

            string folderPath = "";

            string datePath = Path.Combine(savePath, date.ToString("yyyy-MM-dd"));
            string hourPath = Path.Combine(datePath, date.ToString("HH"));
            folderPath = Path.Combine(hourPath, hikFrame.Uuid);
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }
            //hikFrame.Uuid   // 板卡UUID
            //hikFrame.QrCode // 板卡二维码
            //hikFrame.Index  // 图像帧索引
            //lightType       //拍照使用光源类似 -LZC
            string imageName = "";
            if (hikFrame.LightType == GrabLightTypeE.DLPLight)
            {
                imageName = $"{hikFrame.Uuid}_{hikFrame.Index}_{hikFrame.LightType}_{hikFrame.DlpLocationIndex}_{hikFrame.DlpImageIndex}";
            }
            else
            {
                imageName = $"{hikFrame.Uuid}_{hikFrame.Index}_{hikFrame.LightType}";
            }
            string imageFile = Path.Combine(folderPath, imageName + ".jpg");
            var eps = new EncoderParameters(1);
            var ep = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 98L);
            eps.Param[0] = ep;
            var jpsEncodeer = GetEncoder(ImageFormat.Jpeg);
            if (isSaveJpg)
                bitmap.Save(imageFile, jpsEncodeer, eps);
            bitmap.Dispose();
            ep.Dispose();
            eps.Dispose();
            #endregion
        }
        #endregion

        #region 设备参数
        private bool enableParmSet = false;
        public bool EnableParmSet
        {
            get { return enableParmSet; }
            set
            {
                if (enableParmSet != value)
                    enableParmSet = value;
                this.RaisePropertyChanged("EnableParmSet");
            }
        }

        private float[] pfValue = new float[12];
        /// <summary>
        /// X轴正限位
        /// </summary>
        //private float limitP.x;
        //public float limitP.x
        //{
        //    get => this.limitP.x;
        //    set
        //    {
        //        if (value != this.limitP.x)
        //        {
        //            this.limitP.x = value;
        //            this.RaisePropertyChanged("limitP.x");
        //        }
        //    }
        //}
        /// <summary>
        /// X轴负限位
        /// </summary>
        //private float limitN.x;
        //public float limitN.x
        //{
        //    get => this.limitN.x;
        //    set
        //    {
        //        if (value != this.limitN.x)
        //        {
        //            this.limitN.x = value;
        //            this.RaisePropertyChanged("limitN.x");
        //        }
        //    }
        //}
        /// <summary>
        /// Y轴正限位
        /// </summary>
        //private float limitP.y;
        //public float limitP.y
        //{
        //    get => this.limitP.y;
        //    set
        //    {
        //        if (value != this.limitP.y)
        //        {
        //            this.limitP.y = value;
        //            this.RaisePropertyChanged("limitP.y");
        //        }
        //    }
        //}
        /// <summary>
        /// Y轴负限位
        /// </summary>
        //private float limitN.y;
        //public float limitN.y
        //{
        //    get => this.limitN.y;
        //    set
        //    {
        //        if (value != this.limitN.y)
        //        {
        //            this.limitN.y = value;
        //            this.RaisePropertyChanged("limitN.y");
        //        }
        //    }
        //}
        /// <summary>
        /// R轴正限位
        /// </summary>
        private float rFsLimit;
        public float RFsLimit
        {
            get => this.rFsLimit;
            set
            {
                if (value != this.rFsLimit)
                {
                    this.rFsLimit = value;
                    this.RaisePropertyChanged("RFsLimit");
                }
            }
        }
        /// <summary>
        /// R轴负限位
        /// </summary>
        private float rRsLimit;
        public float RRsLimit
        {
            get => this.rRsLimit;
            set
            {
                if (value != this.rRsLimit)
                {
                    this.rRsLimit = value;
                    this.RaisePropertyChanged("RRsLimit");
                }
            }
        }
        /// <summary>
        /// X轴左进起点
        /// </summary>
        private float lrPointX;
        public float LRPointX
        {
            get => this.lrPointX;
            set
            {
                if (value != this.lrPointX)
                {
                    this.lrPointX = value;
                    this.RaisePropertyChanged("LRPointX");
                }
            }
        }
        /// <summary>
        /// Y轴左进起点
        /// </summary>
        private float lrPointY;
        public float LRPointY
        {
            get => this.lrPointY;
            set
            {
                if (value != this.lrPointY)
                {
                    this.lrPointY = value;
                    this.RaisePropertyChanged("LRPointY");
                }
            }
        }
        /// <summary>
        /// X轴右进起点
        /// </summary>
        private float rlPointX;
        public float RLPointX
        {
            get => this.rlPointX;
            set
            {
                if (value != this.rlPointX)
                {
                    this.rlPointX = value;
                    this.RaisePropertyChanged("RLPointX");
                }
            }
        }
        /// <summary>
        /// Y轴右进起点
        /// </summary>
        private float rlPointY;
        public float RLPointY
        {
            get => this.rlPointY;
            set
            {
                if (value != this.rlPointY)
                {
                    this.rlPointY = value;
                    this.RaisePropertyChanged("RLPointY");
                }
            }
        }
        /// <summary>
        /// R轴校正值
        /// </summary>
        private float rCheckVal;
        public float RCheckVal
        {
            get => this.rCheckVal;
            set
            {
                if (value != this.rCheckVal)
                {
                    this.rCheckVal = value;
                    this.RaisePropertyChanged("RCheckVal");
                }
            }
        }

        private bool openWlight = false;

        public bool OpenWlight
        {
            get { return openWlight; }
            set { 
                openWlight = value;
                if (value)
                {
                    //motion.StrobeWhiteTurnOn();
                }
                else
                {
                    //motion.StrobeWhiteTurnOff();
                }
                RaisePropertyChanged("OpenWlight"); 
            }
        }



        private bool openRGBlight = false;

        public bool OpenRGBlight
        {
            get { return openRGBlight; }
            set { 
                openRGBlight = value;
                if (value)
                {
                    //motion.StrobeRGBTurnOn();
                }
                else
                {
                    //motion.StrobeRGBTurnOff();
                }
                RaisePropertyChanged("OpenRGBlight");
            }
        }



        /// <summary>
        /// 获取设置参数
        /// </summary>
        public RelayCommand GetDeviceConfi
        {
            get
            {
                return new RelayCommand(() =>
                {
                    //MotionLib.MT_Status status = motion.GetHardwareConfi(pfValue);
                    //if (status.Code == MotionLib.MT_OK && pfValue[0] == 0xAB12)
                    //{
                    //    limitP.x = pfValue[1];
                    //    limitN.x = pfValue[2];
                    //    limitP.y = pfValue[3];
                    //    limitN.y = pfValue[4];
                    //    RFsLimit = pfValue[5];
                    //    RRsLimit = pfValue[6];
                    //    LRPointX = pfValue[7];
                    //    LRPointY = pfValue[8];
                    //    RLPointX = pfValue[9];
                    //    RLPointY = pfValue[10];
                    //    RCheckVal = pfValue[11];
                    //}
                    EnableParmSet = true;
                });
            }
        }
        /// <summary>
        /// 设置设备参数
        /// </summary>
        //public RelayCommand SetDeviceConfi
        //{
        //    //get
        //    //{
        //    //    //return new RelayCommand(() =>
        //    //    //{
        //    //    //    pfValue[0] = 0xAB12;
        //    //    //    pfValue[1] = limitP.x;
        //    //    //    pfValue[2] = limitN.x;
        //    //    //    pfValue[3] = limitP.y;
        //    //    //    pfValue[4] = limitN.y;
        //    //    //    pfValue[5] = RFsLimit;
        //    //    //    pfValue[6] = RRsLimit;
        //    //    //    pfValue[7] = LRPointX;
        //    //    //    pfValue[8] = LRPointY;
        //    //    //    pfValue[9] = RLPointX;
        //    //    //    pfValue[10] = RLPointY;
        //    //    //    pfValue[11] = RCheckVal;
        //    //    //    motion.SetHardwareConfi(pfValue);
        //    //    //});
        //    //}
        //}
        #endregion
        private void LogCallback(string text)
        {
            LogText += text + "\r\n";
            if (logText.Split('\n').Length >= 1000)
            {
                LogText = "";
            }
        }
        /// <summary>
        /// 循环测试
        /// </summary>
        private List<int> LoopTestCameras = new List<int>();

        private bool LoopFlag = false;
        /// <summary>
        /// 开始循环测试
        /// </summary>
        public RelayCommand StartLoopTest
        {
            get
            {
                return new RelayCommand(() =>
                {
                    cameras.ForEach(itm =>
                    {
                        itm.Length = ProductLength;
                        itm.Width = ProductWidth;
                        itm.LightType = GrabLightTypeE.RGBAndWhiteAndDLP;
                    });
                    if (!LoopFlag)
                    {
                        LoopFlag = true;
                        LoopDetectTest(cameras);
                    }
                });
            }
        }
        /// <summary>
        /// 停止循环测试
        /// </summary>
        public RelayCommand StopLoopTest
        {
            get
            {
                return new RelayCommand(() =>
                {
                    LoopFlag = false;
                });
            }
        }
        ///// <summary>
        ///// 循环测试线程
        ///// </summary>
        private void LoopDetectTest(List<CameraConf> confs)
        {
            Task.Run(() =>
            {
                while (LoopFlag)
                {
                    motion.MT_StartSingleDetect(confs);
                   

                    Thread.Sleep(3000);
                }

                motion.MT_StopSingleDetect(confs);
            });
        }
        /// <summary>
        /// 开始硬件精度测试
        /// </summary>
        public RelayCommand StartHwPrecision
        {
            get
            {
                return new RelayCommand(() =>
                {
                    cameras.ForEach(itm =>
                    {
                        if (!LoopTestCameras.Contains(itm.CamNo))
                        {
                            LoopTestCameras.Add(itm.CamNo);
                            itm.Length = ProductLength;
                            itm.Width = ProductWidth;
                            itm.LightType = GrabLightTypeE.RGBAndWhiteAndDLP;

                            HwPrecisionTest(itm);
                        }
                    });
                });
            }
        }
        /// <summary>
        /// 停止硬件精度测试
        /// </summary>
        public RelayCommand StopHwPrecision
        {
            get
            {
                return new RelayCommand(() =>
                {
                    cameras.ForEach(itm =>
                    {
                        if (LoopTestCameras.Contains(itm.CamNo))
                        {
                            LoopTestCameras.Remove(itm.CamNo);
                        }
                    });
                });
            }
        }
        /// <summary>
        /// 循环测试线程
        /// </summary>
        private void HwPrecisionTest(CameraConf conf)
        {
            Task.Run(() =>
            {
                MotionLib.MT_Status status;
                int step = 0;
                while (LoopTestCameras.Contains(conf.CamNo))
                {
                    switch (step)
                    {
                        case 0:
                            status = motion.MT_ConveyorInput(conf);
                            if (status.Code == MotionLib.MT_OK)
                            {
                                step = 1;
                            }
                            break;
                        case 1:
                            status = motion.MT_StartGrabImage(conf);
                            if (status.Code == MotionLib.MT_OK)
                            {
                                step = 2;
                            }
                            break;
                        case 2:
                            if (conf.TaskState == ModuleTaskStateE.Idle)
                            {
                                step = 1;
                            }
                            break;
                        default:
                            break;
                    }

                    Thread.Sleep(3000);
                }
            });
        }

        #region 通信

        private MessageHeader CurrentMsgCmd = new MessageHeader();

        private MessageHeader HeartMsg = new MessageHeader();
        public int IntCommunication()
        {
            string dirPath1 = AppDomain.CurrentDomain.BaseDirectory;
            dirPath1 += "\\Config\\init.conf";
         
            LogCallback(dirPath1);
            int nWidth = 2448; int nHeight = 2048;

            ConfigHelper.Instance.Init();
            nWidth = Convert.ToInt32(ConfigHelper.Instance.GetValue("MotionSystemConfi", "Width", "2448"));
            nHeight = Convert.ToInt32(ConfigHelper.Instance.GetValue("MotionSystemConfi", "Height", "2048"));



            var iret = CommunicationServerHelper.Instance.Init(nWidth, nHeight, 1);
            LogCallback($"相机像素{nWidth},{nHeight}");

            if (iret != 1)
            {
                LogCallback($"CommunicationServerHelper初始化失败,返回值{iret}");
                return iret;
            }
            LogCallback("CommunicationServerHelper初始化成功");

            return iret;
        }
        private int CurrentID = 0;
        private int ImgCount = 0;
        private bool isLoop = false;
        Mutex GrabMutex = new Mutex();
        /// <summary>
        /// 处理客户端的命令
        /// </summary>
        public void CommunicationLoopMsg()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    CommunicationServerHelper.Instance.ReceiveOneMsg(ref CurrentMsgCmd);
                    if (CurrentMsgCmd.bReaded || CurrentMsgCmd.CmdType == CommandType.None || CurrentMsgCmd.CmdType == CommandType.Heartbeat)
                    {
                        //消息已读,或者为空消息
                        Thread.Sleep(500);
                        continue;
                    }
                    addLog(CurrentMsgCmd, true);
                    //没有连接的时，必须先初始化。
                    if (!IsClientConnect && CurrentMsgCmd.CmdType != CommandType.Init) continue;

                    switch (CurrentMsgCmd.CmdType)
                    {
                        case CommandType.None:
                            break;
                        case CommandType.Init:
                            InitCmd(CurrentMsgCmd);
                            break;
                        case CommandType.GrabInit:
                            GrabInitCmd(CurrentMsgCmd);
                            break;
                        case CommandType.SingleGrab:
                            SingleCapture(CurrentMsgCmd);
                            break;
                        case CommandType.SinglePanelGrab:
                            GrabSinglePanelCmd(CurrentMsgCmd);
                            break;
                        case CommandType.Running:
                            StartRuningCmd(CurrentMsgCmd);
                            break;
                        case CommandType.StopRunning:
                            StopRunningCmd(CurrentMsgCmd);
                            break;
                        case CommandType.Reset:
                            ResetCmd(CurrentMsgCmd);
                            break;
                        case CommandType.Move_T_abs:
                            Move_absCmd(CurrentMsgCmd);
                            break;
                        case CommandType.Move_T_add:
                            break;
                        case CommandType.NGSignalOutputType:
                            NGSignalOutputTypeCmd(CurrentMsgCmd);
                            break;
                        case CommandType.PidNGSignal:
                            PidNGSignal(CurrentMsgCmd);
                            break;
                        case CommandType.Heartbeat:
                            //HeartbeatCmd(CurrentMsgCmd);
                            break;
                        case CommandType.PanelRestRunningLoop:
                            PanelRestRunningLoopCmd(CurrentMsgCmd);
                            break;
                        case CommandType.RunningLoop:
                            RunningLoopCmd(CurrentMsgCmd);
                            break;
                        case CommandType.RunningToGrab://开始采集
                            RunningToGrabCmd(CurrentMsgCmd);
                            break;
                        case CommandType.MoveAxis:
                            MoveAxisCmd(CurrentMsgCmd);
                            break;
                        default:
                            break;
                    }
                    Thread.Sleep(1000);
                }
            });
        }
        void SingleCapture(MessageHeader message)
        {
            var lighttype = (GrabLightTypeE)message.Para_1;

            MessageHeader msg = new MessageHeader();
            if (m_bPassMode)
            {
                LogCallback("直通中,无法启动");
                msg.ReTurnType = ResponseType.ERROR;
                CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
                return;
            }
            if (motion.MT_GrabSingleImageX(GetCurrentCamera(), lighttype).Code == MT_OK)
            {
                msg.Para_5 = CurrentID;
                msg.ReTurnType = ResponseType.OK;
            }
            else
            {
                msg.ReTurnType = ResponseType.ERROR;
            }
            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            addLog(msg, false);
        }
        void MoveAxisCmd(MessageHeader message)
        {
            AxisE axis = (AxisE)message.Para_1;
            bool abs = message.Para_2 == 1;
            double dis = message.Para_6;

            MessageHeader msg = new MessageHeader();

            if (abs)
            {
                if (motion.MT_MoveAbs(GetCurrentCamera(), axis, (float)dis).Code == MT_OK)
                {
                    msg.ReTurnType = ResponseType.OK;
                }
                else
                {
                    msg.ReTurnType = ResponseType.ERROR;
                }
            }
            else
            {
                if (motion.MT_MoveRel(GetCurrentCamera(), axis, (float)dis).Code == MT_OK)
                {
                    msg.ReTurnType = ResponseType.OK;
                }
                else
                {
                    msg.ReTurnType = ResponseType.ERROR;
                }
            }
            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            addLog(msg, false);
        }
        private void GetState(ref MessageHeader msg)
        {
            CameraConf conf = GetCurrentCamera();
            if (conf == null)
            {
                msg.ReTurnType = ResponseType.ERROR;
                return;
            }

            motion.MTGetState(conf, ref msg.Para_5, ref msg.Para_4);

            motion.MT_GetAxisPosition(conf, AxisE.X, ref msg.Para_10);
            motion.MT_GetAxisPosition(conf, AxisE.Y, ref msg.Para_9);

            msg.ReTurnType = ResponseType.OK;
        }
        /// <summary>
        /// 处理客户端的心跳
        /// </summary>
        public void CommunicationHeartMsg()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    CommunicationServerHelper.Instance.ReceiveOneHeartMsg(ref HeartMsg);
                    if (HeartMsg.bReaded || HeartMsg.CmdType != CommandType.Heartbeat)
                    {
                        //消息已读,或者为空消息
                        Thread.Sleep(200);
                        continue;
                    }
                    //addLog(HeartMsg, true);
                    MessageHeader msg = new MessageHeader();
                    if (IsConnected)
                    {
                        msg.ReTurnType = ResponseType.OK;
                        //状态发送给客户端
                        GetState(ref msg);
                    }
                    else
                        msg.ReTurnType = ResponseType.ERROR;

                    //掉线的首次连接
                    if(!IsClientConnect)
                    {
                        //重置buffer区
                        CommunicationServerHelper.Instance.ResetBuffer();
                        IsClientConnect = true;
                    }
                    CommunicationServerHelper.Instance.RespondOneHeartMsg(ref HeartMsg, ref msg);
                    //addLog(msg, false);
                    Thread.Sleep(500);
                }
            });
        }
        void addLog(MessageHeader ReceiveMsg, bool getOrPot)
        {
            if (ReceiveMsg.bReaded) return;
            if (getOrPot)
            {
                LogCallback($"ReceiveMsg,ID:{ReceiveMsg.MessageID}，Rid:{ReceiveMsg.AnswerMsgID},Cmd:{ReceiveMsg.CmdType}，Rtype:{ReceiveMsg.ReTurnType}，{ReceiveMsg.Timestamp}，p1：{ReceiveMsg.Para_1},p2:{ReceiveMsg.Para_2}");
            }
            else
            {
                LogCallback($"SendOneMsg,ID:{ReceiveMsg.MessageID}，Rid:{ReceiveMsg.AnswerMsgID},Cmd:{ReceiveMsg.CmdType}，Rtype:{ReceiveMsg.ReTurnType}，{ReceiveMsg.Timestamp}，p1：{ReceiveMsg.Para_1},p2:{ReceiveMsg.Para_2}");
            }
        }
        void InitCmd(MessageHeader message)
        {
            CommunicationServerHelper.Instance.ResetBuffer();
            MessageHeader msg = new MessageHeader();
            //msg.ReTurnType = ResponseType.OK;
            if (IsConnected) msg.ReTurnType = ResponseType.OK;
            else msg.ReTurnType = ResponseType.ERROR;
            IsClientConnect = true;
            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            addLog(msg, false);
        }
        void HeartbeatCmd(MessageHeader ReceivedMsg)
        {
            MessageHeader msg = new MessageHeader();
            msg.ReTurnType = ResponseType.OK;
            //if (IsConnected) msg.ReTurnType = ResponseType.OK;
            //else msg.ReTurnType = ResponseType.ERROR;
            IsClientConnect = true;
            CommunicationServerHelper.Instance.RespondOneHeartMsg(ref ReceivedMsg, ref msg);
            addLog(msg, false);
        }
        void GrabInitCmd(MessageHeader message)
        {
            CommunicationServerHelper.Instance.ResetBuffer();

            CameraConf conf = GetCurrentCamera();
            conf.Length = (float)message.Para_6;
            conf.Width = (float)message.Para_7;
            float startx = (float)message.Para_8;
            float starty = (float)message.Para_9;
            motion.MT_GetProductAttri(conf, startx, starty);
            MessageHeader msg = new MessageHeader();
            msg.ReTurnType = ResponseType.OK;
            msg.Para_1 = conf.pcbAttri.Column;
            msg.Para_2 = conf.pcbAttri.Row;
            msg.Para_5 = CurrentID;
            conf.LightType = GrabLightTypeE.RGBAndDLP;
            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            addLog(msg, false);
        }
        void StartRuningCmd(MessageHeader message)
        {
            MessageHeader msg = new MessageHeader();

            msg.ReTurnType = ResponseType.OK;

            if (m_bPassMode)
            {
                LogCallback("直通中,无法启动");
                msg.ReTurnType = ResponseType.ERROR;
                CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
                return;
            }

            GrabMutex.WaitOne();
            CurrentID = 0;
            ImgCount = 0;
            m_bWidthStart = false;
            LogCallback("CommunicationServerHelper-开始检测");
          
            MotionLib.MT_Status status = motion.MT_StartDetect(cameras);
            GrabMutex.ReleaseMutex();

            if (status.Code != MotionLib.MT_OK)
            {
                LogCallback("开始检测异常,运行失败"); 
                msg.ReTurnType = ResponseType.ERROR;
                CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            }
        }
        void StopRunningCmd(MessageHeader message)
        {
            isLoop = false;

           
            LogCallback("CommunicationServerHelper-停止检测");
            motion.MT_StopDetect(cameras);
        }
        void GrabSinglePanelCmd(MessageHeader message)
        {
            MessageHeader msg = new MessageHeader();

            msg.ReTurnType = ResponseType.OK;
            if (m_bPassMode)
            {
                LogCallback("直通中,无法启动");
                msg.ReTurnType = ResponseType.ERROR;
                CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
                return;
            }

            GrabMutex.WaitOne();
            CurrentID = 0;
            ImgCount = 0;
            CameraConf conf = GetCurrentCamera();
            conf.LightType = GrabLightTypeE.RGBAndDLP;

            m_bWidthStart = false;
            LogCallback("CommunicationServerHelper-单次取图");
            MotionLib.MT_Status status =  motion.MT_StartGrabImage(conf);
            GrabMutex.ReleaseMutex();

            if (status.Code != MotionLib.MT_OK)
            {
                LogCallback("单次取图异常,运行失败");
                msg.ReTurnType = ResponseType.ERROR;
                CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            }

            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
        }
        void PanelRestRunningLoopCmd(MessageHeader message)
        {

            if (m_bPassMode)
            {
                LogCallback("直通中,无法启动"); return;
            }
            CurrentID = 0;
            ImgCount = 0;
            CameraConf conf = GetCurrentCamera();
            isLoop = true;
            conf.LightType = GrabLightTypeE.RGBAndDLP;

            MotionLib.MT_Status status;     bool bNG = false;
            m_bWidthStart = false;
            LogCallback("CommunicationServerHelper-循环取图");
            Task.Run(() =>
            {
                GrabMutex.WaitOne();
                Thread.Sleep(10000);
                while (isLoop)
                {
                    status = motion.MT_StartGrabImage(GetCurrentCamera());
                    if (status.Code != MotionLib.MT_OK)
                    {
                        bNG = true; isLoop = false;
                        break;
                    }
                    Thread.Sleep(40000);
                }
                GrabMutex.ReleaseMutex();
            });

            if (bNG)
            {
                LogCallback("循环取图异常,终止循环检测");
            }

        }
        void RunningLoopCmd(MessageHeader message)
        {
            if (m_bPassMode)
            {
                LogCallback("直通中,无法启动"); return;
            }

            CurrentID = 0;
            ImgCount = 0;
            isLoop = true;
            MotionLib.MT_Status status; bool bNG = false;

            m_bWidthStart = false;
            LogCallback("CommunicationServerHelper-开始单次循环检测");
            Task.Run(() =>
            {
                UInt32 grabCount = 0;
                UInt32 currentGrabCount = 0;
                while (isLoop)
                {
                    if (grabCount == 0 || grabCount != currentGrabCount)
                    {
                        grabCount = currentGrabCount;
                        GrabMutex.WaitOne();
                        status = motion.MT_StartSingleDetect(cameras);
                        GrabMutex.ReleaseMutex();
                        if (status.Code != MotionLib.MT_OK)
                        {
                            bNG = true; isLoop = false;
                            break;
                        }
                    }
                    Thread.Sleep(3000);
                    status = motion.MT_GetGrabRoundCount(GetCurrentCamera(), out currentGrabCount);
                    if (status.Code != MotionLib.MT_OK)
                    {
                        bNG = true; isLoop = false;
                        break;
                    }
                }
                motion.MT_StopSingleDetect(cameras); 
            });

            if (bNG)
            {
                LogCallback("单次循环检测异常,终止循环检测");
            }

        }
        void RunningToGrabCmd(MessageHeader message)
        {
            GrabMutex.WaitOne();

            MessageHeader msg = new MessageHeader();

            msg.ReTurnType = ResponseType.OK;

            if (m_bPassMode)
            {
                LogCallback("直通中,无法采集");
                msg.ReTurnType = ResponseType.ERROR;
                CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
                GrabMutex.ReleaseMutex();
                return;
            }

            MotionLib.MT_Status status = motion.MT_StartGrab(GetCurrentCamera());

            if (status.Code != MotionLib.MT_OK)
            {
                LogCallback("尝试采集失败");
                msg.ReTurnType = ResponseType.ERROR;
            }
            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            GrabMutex.ReleaseMutex();
        }

        void ResetCmd(MessageHeader message)
        {
            motion.MT_StopDetect(cameras);

            //ButtonColor = new SolidColorBrush(Colors.Green);
            //MyText = "直通模式开";
            //LogCallback("CommunicationServerHelper-设备复位");
            m_bWidthStart = false;
            motion.MT_MachineReset(GetCurrentCamera());
        }
        void Move_absCmd(MessageHeader message)
        {
        
            MessageHeader msg = new MessageHeader();

            if (motion.MT_SetConveyorWidth(GetCurrentCamera(), (float)message.Para_6).Code == MT_OK)
            {
                msg.ReTurnType = ResponseType.OK;
            }
            else
            {
                msg.ReTurnType = ResponseType.ERROR;
            }
            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            addLog(msg, false);
        }
        void NGSignalOutputTypeCmd(MessageHeader message)
        {
            motion.MT_SetCheckResultMode(GetCurrentCamera(), (int)message.Para_1);
            MessageHeader msg = new MessageHeader();
            msg.ReTurnType = ResponseType.OK;
            CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
        }
        void PidNGSignal(MessageHeader message)
        {

          

            if (message.Para_1.ToString() == null)
            {
              

                LogCallback($"进入PidNGSignal-NULL");
                return;
            }
            if (message.Para_2 == -1)
            {
             
                LogCallback($"进入PidNGSignal-进入蜂鸣器");
                //蜂鸣器响起来
                motion.MT_OpenBeep(GetCurrentCamera());
            }
            else if (message.Para_2 == 0  || message.Para_2 == 1) 
            {
                //蜂鸣器关闭
                LogCallback($"进入PidNGSignal-蜂鸣器关闭");
                motion.MT_CloseBeep(GetCurrentCamera());
                motion.MT_SetCheckResultValue(GetCurrentCamera(), message.Para_1.ToString(), message.Para_2 == 1);
                MessageHeader msg = new MessageHeader();
                msg.ReTurnType = ResponseType.OK;
                CommunicationServerHelper.Instance.RespondOneMsg(ref message, ref msg);
            }
           
        }
        #endregion
    }

    public class IoModel : ViewModelBase
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Content { get; set; }
        private bool isChecked;
        public bool IsChecked
        {
            get => isChecked;
            set
            {
                if (isChecked != value)
                {
                    isChecked = value;
                    RaisePropertyChanged();
                }
            }
        }
    }


    public class StrobeWhiteItem : ViewModelBase 
    {
        private int index = 0;
        /// <summary>
        /// 拍照索引
        /// </summary>
        public int Index
        {
            get { return index; }
            set { index = value; RaisePropertyChanged(); }
        }


        private  GrabLightTypeE lightTyoe = GrabLightTypeE.RGBLight;
        /// <summary>
        /// 启用白光
        /// </summary>
        public GrabLightTypeE LightType
        {
            get { return lightTyoe; }
            set { lightTyoe = value; RaisePropertyChanged(); }
        }
    }
}
